package io.renren.modules.aic.service.impl;

import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.modules.aic.dao.MemberDao;
import io.renren.modules.aic.dao.MemberMachineDao;
import io.renren.modules.aic.dao.TeamDao;
import io.renren.modules.aic.entity.BalanceDetailEntity;
import io.renren.modules.aic.entity.MemberEntity;
import io.renren.modules.aic.entity.MemberMachineEntity;
import io.renren.modules.aic.service.BalanceDetailService;
import io.renren.modules.aic.service.MemberMachineService;
import io.renren.modules.aic.service.MemberService;
import io.renren.modules.sys.service.SysConfigService;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("memberMachineService")
public class MemberMachineServiceImpl extends ServiceImpl<MemberMachineDao, MemberMachineEntity> implements MemberMachineService {

	@Autowired
	MemberService memberService;

	@Autowired
	MemberDao memberDao;

	@Autowired
	MemberMachineDao memberMachineDao;

	@Autowired
	TeamDao teamDao;

	@Autowired
	BalanceDetailService balanceDetailService;

	@Autowired
	SysConfigService sysConfigService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String status = (String) params.get("status");
		String mobile = (String) params.get("mobile");
		Long memberId = null;
		if (StringUtils.isNotBlank(mobile)) {
			MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().eq("mobile", mobile));
			if (member == null) {
				memberId = Long.MIN_VALUE;
			} else {
				memberId = member.getId();

			}
		}
		Page<MemberMachineEntity> page = this.selectPage(new Query<MemberMachineEntity>(params).getPage(),
				new EntityWrapper<MemberMachineEntity>().eq(StringUtils.isNotBlank(status), "status", status).eq(memberId != null, "member_id", memberId));
		List<MemberMachineEntity> list = page.getRecords();
		if (!CollectionUtils.isEmpty(list)) {
			for (MemberMachineEntity memberMachineEntity : list) {
				MemberEntity member = memberService.selectById(memberMachineEntity.getMemberId());
				memberMachineEntity.setMobile(member.getMobile());
			}
		}

		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void changeStatus(Long[] ids, String type) {
		MemberMachineEntity entity = new MemberMachineEntity();
		entity.setUpdateTime(new Date());
		entity.setStatus("START".equals(type) ? ProjectConstant.MACHINE_RUNSTATUS_RUNNING : ProjectConstant.MACHINE_RUNSTATUS_PAUSE);
		this.update(entity, new EntityWrapper<MemberMachineEntity>().in("id", ids));

		// 计算矿工等级
		Set<Long> memberIds = new HashSet<Long>();
		for (Long mmId : ids) {
			memberIds.add(this.selectById(mmId).getMemberId());
		}
		memberService.calcUserLevel(memberIds);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteMemberMachine(Long[] ids) {

		Set<Long> memberIds = new HashSet<Long>();
		for (Long mmId : ids) {
			memberIds.add(this.selectById(mmId).getMemberId());
		}

		this.deleteBatchIds(Arrays.asList(ids));
		// 计算矿工等级
		memberService.calcUserLevel(memberIds);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void minerProfit() {

		// 会员总推荐奖励
		Map<Long, BigDecimal> total = new HashMap<Long, BigDecimal>();
		int one = sysConfigService.getValueI(ConfigConstant.ENABLE_LEVEL_ONE);// 直推奖励会员需要达到体验矿工
		int two = sysConfigService.getValueI(ConfigConstant.ENABLE_LEVEL_TWO);// 二代奖励会员需要达到一级矿工
		int three = sysConfigService.getValueI(ConfigConstant.ENABLE_LEVEL_THREE);// 三代奖励会员需要达到二级矿工

		// 直推会员
		List<Long> memeberIds = teamDao.groupByHigher(ProjectConstant.REC_LEVEL_ONE);
		if (CollectionUtils.isNotEmpty(memeberIds)) {
			for (Long id : memeberIds) {

				// 会员等级是否达到直推奖励限制
				MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("user_level").eq("id", id));
				if (member.getUserLevel() < one) {
					continue;
				}

				List<BigDecimal> memberTodayProfitList = memberDao.sumTodayProfit(ProjectConstant.REC_LEVEL_ONE, id);
				if (CollectionUtils.isNotEmpty(memberTodayProfitList)) {

					BigDecimal reward = new BigDecimal(sysConfigService.getValue(ConfigConstant.REC_LEVEL_ONE));// 直推5%
					BigDecimal ttp = total.get(id) == null ? new BigDecimal("0") : total.get(id);// 当日总收益
					BigDecimal mtp = memberDao.myTodayProfit(id);// 我的矿机当日总收益
					mtp = mtp == null ? new BigDecimal("0") : mtp;
					for (BigDecimal memberTodayProfit : memberTodayProfitList) {

						// 处理烧伤
						if (mtp.compareTo(memberTodayProfit) == -1) {
							ttp = ttp.add(mtp.multiply(reward));
						} else {
							ttp = ttp.add(memberTodayProfit.multiply(reward));
						}

					}

					total.put(id, ttp);
				}
			}
		}

		// 二级会员
		memeberIds = teamDao.groupByHigher(ProjectConstant.REC_LEVEL_TWO);
		if (CollectionUtils.isNotEmpty(memeberIds)) {
			for (Long id : memeberIds) {

				// 会员等级是否达到二代奖励限制
				MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("user_level").eq("id", id));
				if (member.getUserLevel() < two) {
					continue;
				}

				List<BigDecimal> memberTodayProfitList = memberDao.sumTodayProfit(ProjectConstant.REC_LEVEL_TWO, id);
				if (CollectionUtils.isNotEmpty(memberTodayProfitList)) {

					BigDecimal reward = new BigDecimal(sysConfigService.getValue(ConfigConstant.REC_LEVEL_TWO));// 二级3%
					BigDecimal ttp = total.get(id) == null ? new BigDecimal("0") : total.get(id);// 当日总收益

					BigDecimal mtp = memberDao.myTodayProfit(id);// 我的矿机当日总收益
					for (BigDecimal memberTodayProfit : memberTodayProfitList) {

						// 处理烧伤
						if (mtp.compareTo(memberTodayProfit) == -1) {
							ttp = ttp.add(mtp.multiply(reward));
						} else {
							ttp = ttp.add(memberTodayProfit.multiply(reward));
						}

					}

					total.put(id, ttp);

				}
			}
		}

		// 三级会员
		memeberIds = teamDao.groupByHigher(ProjectConstant.REC_LEVEL_THREE);
		if (CollectionUtils.isNotEmpty(memeberIds)) {
			for (Long id : memeberIds) {

				// 会员等级是否达到三代奖励限制
				MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("user_level").eq("id", id));
				if (member.getUserLevel() < three) {
					continue;
				}

				List<BigDecimal> memberTodayProfitList = memberDao.sumTodayProfit(ProjectConstant.REC_LEVEL_THREE, id);
				if (CollectionUtils.isNotEmpty(memberTodayProfitList)) {

					BigDecimal reward = new BigDecimal(sysConfigService.getValue(ConfigConstant.REC_LEVEL_THREE));// 三级2%
					BigDecimal ttp = total.get(id) == null ? new BigDecimal("0") : total.get(id);// 当日总收益
					BigDecimal mtp = memberDao.myTodayProfit(id);// 我的矿机当日总收益
					for (BigDecimal memberTodayProfit : memberTodayProfitList) {

						// 处理烧伤
						if (mtp.compareTo(memberTodayProfit) == -1) {
							ttp = ttp.add(mtp.multiply(reward));
						} else {
							ttp = ttp.add(memberTodayProfit.multiply(reward));
						}

					}

					total.put(id, ttp);

				}
			}
		}

		// 更新会员收益
		Date now = new Date();
		for (Long id : total.keySet()) {
			BigDecimal value = total.get(id);

			// 更新会员余额
			MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id", "balance").eq("id", id));
			member.setBalance(value.add(new BigDecimal(member.getBalance().toString())).doubleValue());
			member.setUpdateTime(now);
			memberService.updateById(member);

			// 插入资金流水
			BalanceDetailEntity bd = new BalanceDetailEntity();
			bd.setMemberId(id);
			bd.setBalanceChange(value.doubleValue());
			bd.setCategory(3);// 推广奖励
			bd.setCreateTime(now);
			balanceDetailService.insert(bd);
		}

		// 更新运行中的矿机当天收益
		memberMachineDao.updatePreProfit();
	}
}
